/*
* We can't use kernel_thread since we must avoid to reschedule the child.
*/
- if ( (idle = do_newdomain()) == NULL )
+ if ( (idle = do_newdomain(IDLE_DOMAIN_ID, cpu)) == NULL )
panic("failed 'newdomain' for CPU %d", cpu);
- idle->processor = cpu;
- idle->domain = IDLE_DOMAIN_ID;
pagetable = (void *)get_free_page(GFP_KERNEL);
memcpy(pagetable, idle0_pg_table, PAGE_SIZE);
idle_pg_table[cpu] = pagetable;
static unsigned int pro = 0;
unsigned int dom = get_domnr();
ret = -ENOMEM;
- if ( !dom ) break;
- p = do_newdomain();
- if ( !p ) break;
- p->domain = dom;
+ if ( dom == 0 ) break;
pro = (pro+1) % smp_num_cpus;
- p->processor = pro;
-
- if ( dom == 0 ) BUG();
+ p = do_newdomain(dom, pro);
+ if ( p == NULL ) break;
ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
if ( ret != 0 ) break;
/*
* create a new domain
*/
-struct task_struct *do_newdomain(void)
+struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
{
int retval;
struct task_struct *p = NULL;
p = alloc_task_struct();
if (!p) goto newdomain_out;
memset(p, 0, sizeof(*p));
+
+ p->domain = dom_id;
+ p->processor = cpu;
+
p->shared_info = (void *)get_free_page(GFP_KERNEL);
memset(p->shared_info, 0, PAGE_SIZE);
+ SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), dom_id);
SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
destroy_net_vif(p);
}
if ( p->mm.perdomain_pt ) free_page((unsigned long)p->mm.perdomain_pt);
+
+ UNSHARE_PFN(virt_to_page(p->shared_info));
free_page((unsigned long)p->shared_info);
free_all_dom_mem(p);
}
-void construct_cmdline(char *dst, struct task_struct *p)
-{
- int dom = p->domain;
- unsigned char boot[150];
- unsigned char ipbase[20], nfsserv[20], gateway[20], netmask[20];
- unsigned char nfsroot[70];
-
- if ( strcmp("",opt_nfsroot) )
- {
- /* NFS root for Xenolinux. */
- snprintf(nfsroot, 70, opt_nfsroot, dom);
- snprintf(boot, 200,
- " root=/dev/nfs ip=%s:%s:%s:%s::eth0:off nfsroot=%s",
- quad_to_str(opt_ipbase + dom, ipbase),
- quad_to_str(opt_nfsserv, nfsserv),
- quad_to_str(opt_gateway, gateway),
- quad_to_str(opt_netmask, netmask),
- nfsroot);
- }
- else
- {
- /* Non-NFS root for Xenolinux. */
- snprintf(boot, 200,
- " ip=%s::%s:%s::eth0:off",
- quad_to_str(opt_ipbase + dom, ipbase),
- quad_to_str(opt_gateway, gateway),
- quad_to_str(opt_netmask, netmask));
- }
-
- strcpy(dst, boot);
-}
-
-
/* final_setup_guestos is used for final setup and launching of domains other
* than domain 0. ie. the domains that are being built by the userspace dom0
* domain builder.
unsigned long phys_l2tab;
net_ring_t *net_ring;
net_vif_t *net_vif;
- char *dst; // temporary
- int i; // temporary
/* entries 0xe0000000 onwards in page table must contain hypervisor
* mem mappings - set them up.
/* Add block io interface */
virt_startinfo_addr->blk_ring = (blk_ring_t *)SH2G(p->blk_ring_base);
- dst = virt_startinfo_addr->cmd_line;
- if ( mod[0].string )
- {
- char *modline = (char *)__va(mod[0].string);
- for ( i = 0; i < 255; i++ )
- {
- if ( modline[i] == '\0' ) break;
- *dst++ = modline[i];
- }
- }
- *dst = '\0';
-
- construct_cmdline(dst, p);
+ /* Copy the command line */
+ strcpy(virt_startinfo_addr->cmd_line, meminfo->cmd_line);
/* Reinstate the caller's page tables. */
__asm__ __volatile__ (
}
*dst = '\0';
- construct_cmdline(dst, p);
-
-
/* Reinstate the caller's page tables. */
__write_cr3_counted(pagetable_val(current->mm.pagetable));
__sti();
void start_of_day(void);
/* Command line options and variables. */
-unsigned long opt_ipbase=0, opt_nfsserv=0, opt_gateway=0, opt_netmask=0;
-unsigned char opt_nfsroot[50]="";
+unsigned long opt_dom0_ip = 0;
unsigned int opt_dom0_mem = 16000; /* default kbytes for DOM0 */
unsigned int opt_ne_base = 0; /* NE2k NICs cannot be probed */
unsigned char opt_ifname[10] = "eth0";
int type;
void *var;
} opts[] = {
- { "ipbase", OPT_IP, &opt_ipbase },
- { "nfsserv", OPT_IP, &opt_nfsserv },
- { "gateway", OPT_IP, &opt_gateway },
- { "netmask", OPT_IP, &opt_netmask },
- { "nfsroot", OPT_STR, &opt_nfsroot },
+ { "dom0_ip", OPT_IP, &opt_dom0_ip },
{ "dom0_mem", OPT_UINT, &opt_dom0_mem },
{ "ne_base", OPT_UINT, &opt_ne_base },
{ "ifname", OPT_STR, &opt_ifname },
/* Create initial domain 0. */
dom0_params.num_vifs = 1;
dom0_params.memory_kb = opt_dom0_mem;
- add_default_net_rule(0, opt_ipbase); // add vfr info for dom0
- new_dom = do_newdomain();
+ if ( opt_dom0_ip == 0 )
+ panic("Must specify an IP address for domain 0!\n");
+
+ add_default_net_rule(0, opt_dom0_ip); // add vfr info for dom0
+
+ new_dom = do_newdomain(0, 0);
if ( new_dom == NULL ) panic("Error creating domain 0\n");
- new_dom->processor = 0;
- new_dom->domain = 0;
if ( setup_guestos(new_dom, &dom0_params) != 0 )
{
panic("Could not set up DOM0 guest OS\n");
iph->id = 0xdead;
iph->ttl = 255;
iph->protocol= 17;
- iph->daddr = htonl(opt_ipbase);
+ iph->daddr = htonl(opt_dom0_ip);
iph->saddr = htonl(0xa9fe0001);
iph->tot_len = htons(hdr_size + len);
iph->check = 0;
#define capable(_c) 0
#ifndef __ASSEMBLY__
-extern unsigned long opt_ipbase, opt_nfsserv, opt_gateway, opt_netmask;
-extern unsigned char opt_nfsroot[];
extern void __out_of_line_bug(int line) __attribute__((noreturn));
#define out_of_line_bug() __out_of_line_bug(__LINE__)
#endif
#define PageSetSlab(page) set_bit(PG_slab, &(page)->flags)
#define PageClearSlab(page) clear_bit(PG_slab, &(page)->flags)
+#define SHARE_PFN_WITH_DOMAIN(_pfn, _dom) \
+ do { \
+ (_pfn)->flags = (_dom) | PGT_writeable_page; \
+ (_pfn)->tot_count = (_pfn)->type_count = 1; \
+ } while ( 0 )
+
+#define UNSHARE_PFN(_pfn) \
+ (_pfn)->flags = (_pfn)->type_count = (_pfn)->tot_count = 0
+
/* The array of struct pfn_info,
* free pfn list and number of free pfns in the free list
*/
extern union task_union idle0_task_union;
extern struct task_struct first_task_struct;
-extern struct task_struct *do_newdomain(void);
+extern struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu);
extern int setup_guestos(struct task_struct *p, dom0_newdomain_t *params);
extern int final_setup_guestos(struct task_struct *p, dom_meminfo_t *);